/*
 * file.c
 *
 *  Created on: Jun 21, 2011
 *      Author: sainw
 */
#define _XOPEN_SOURCE 500	/* strptime() */
#define _BSD_SOURCE			/* scandir(), timegm() */
#define NETWORK_TIMEOUT 30

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <signal.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <linux/limits.h>
#include <netdb.h>
#include <ctype.h>
#include <errno.h>
#include <dlfcn.h>
#include <time.h>
#include <libgen.h>

#include "file.h"

void download_file(FILE *cgiOut, char *file) {
	//fprintf(stderr, "get_file: (%s) \n", file);
	FILE *fin, *fout;
	FILE* fp;
	int ch;

	fin = fopen(file, "r");
	if (fin == NULL) {
		fprintf(stderr, "Cannot open for reading\n");
		return (-1);
	}

	while ((ch = fgetc(fin)) != EOF)
		fputc(ch, cgiOut);
	fclose(fin);
	fclose(cgiOut);
	return (0);
}

const char * file_mime_lookup(const char *path) {
	struct mimetype *m = &mime_types[0];
	const char *e;

	while (m->extn) {
		e = &path[strlen(path) - 1];

		while (e >= path) {
			if ((*e == '.') && !strcasecmp(&e[1], m->extn))
				return m->mime;

			e--;
		}

		m++;
	}

	return "application/octet-stream";
}

static char * file_unix2date(time_t ts) {
	  struct tm * timeinfo;
	  int year, month ,day;
	  char * weekday[] = { "Sunday", "Monday",
	                       "Tuesday", "Wednesday",
	                       "Thursday", "Friday", "Saturday"};

	static char str[128];

	if(ts==NULL) {
			fprintf(stderr, "null time");

	}
	timeinfo= localtime(&ts);

	strftime(str, sizeof(str), "%a, %d %b %Y %H:%M:%S", timeinfo);
//	printf("date:%s\n",str);

//  printf ("That day is a %s.\n", weekday[timeinfo->tm_wday]);
	return str;
}

static int scandir_filter_dir(const struct dirent *e) {
//	fprintf(stderr, "d_name:%s\n",e->d_name);

	return strcmp(e->d_name, ".") ? 1 : 0;
}

void scan_dir(FILE *out,const char *path) {
	int i;
	int count = 0;
	char filename[PATH_MAX];
	char *pathptr;
	struct dirent **files = NULL;
	struct stat s;
	int first=0;

	if ((count = scandir(path, &files, scandir_filter_dir, alphasort)) > 0) {

		memset(filename, 0, sizeof(filename));
//		memcpy(filename, path, sizeof(filename));//BUG!!!
		memcpy(filename, path, strlen(path));
		pathptr = &filename[strlen(filename)];


		//seteuid(1000);
		/* list subdirs */
		for (i = 0; i < count; i++) {
			strncat(filename, files[i]->d_name,
					sizeof(filename) - strlen(files[i]->d_name));

			if (!stat(filename, &s) && (s.st_mode & S_IFDIR) //&& (s.st_mode& S_IXOTH)
					//&& !(S_ISLNK(s.st_mode))
					&& files[i]->d_name[0]!='.')
//				printf("name:%s,%s,%s,%s, %.02f kbyte\n", "pi->name",
//						files[i]->d_name, files[i]->d_name,
//						file_unix2date(s.st_mtime), s.st_size / 1024.0);
//				first=1;
			fprintf(out,"%s{\"type\":\"folder\",\"size\":\"%.02fkbyte\",\"name\":\"%s\",\"mime-type\":\"-\",\"date\":\"%s\"}",first++==0?"":",",s.st_size / 1024.0,files[i]->d_name,file_unix2date(s.st_mtime));
			*pathptr = 0;
		}

		/* list files */
//		first=0;
		for (i = 0; i < count; i++) {
			strncat(filename, files[i]->d_name,
					sizeof(filename) - strlen(files[i]->d_name));

			if (!stat(filename, &s) && !(s.st_mode & S_IFDIR) && (s.st_mode
					& S_IROTH) && !(S_ISLNK(s.st_mode)) && files[i]->d_name[0]!='.')
//				printf("name:%s,%s,%s,%s,%s,%.02f kbyte\n", "pi->name",
//						files[i]->d_name, files[i]->d_name,
//						file_unix2date(s.st_mtime), file_mime_lookup(filename),
//						s.st_size / 1024.0);
//				first=1;
			fprintf(out,"%s{\"type\":\"file\",\"size\":\"%.02fkbyte\",\"name\":\"%s\",\"mime-type\":\"%s\",\"date\":\"%s\"}",first++==0?"":",",s.st_size / 1024.0,files[i]->d_name,file_mime_lookup(filename),file_unix2date(s.st_mtime));
			*pathptr = 0;
		}
		//fprintf("{\"menuitem\": [{\"value\": \"New\", \"onclick\": \"CreateNewDoc()\"},{\"value\": \"Close\", \"onclick\": \"CloseDoc()\"}]}");
	}else{
		return 0;
	}

	out: if (files) {
		for (i = 0; i < count; i++)
			free(files[i]);

		free(files);
	}
}

int upload_file(char *name,cgiFilePtr file,FILE *cgiOut)
{
	char buffer[1024];
	int got;

	FILE *fout;
	FILE* fp;
	int ch;

//	fprintf(cgiOut, "<span>Before Open:%s</span>\n",name);
	fout = fopen(name, "w+");
	if (fout == NULL) {
//		fprintf(cgiOut, "<span>Cannot open for writing</span>\n");
//		fprintf(stderr, "\n");
		return (-1);
	}


//		fprintf(cgiOut, "Before Write\n");
//  while ((ch = fgetc(file.in)) != EOF)
//	fputc(ch, fout);
//  fclose(fout); fclose(file->in);
//  return(0);
//
	int i;
	while (cgiFormFileRead(file, buffer, sizeof(buffer), &got) ==
		cgiFormSuccess)
	{
		i=0;
		while (i<got)
			fputc(buffer[i++], fout);

//		fwrite(buffer,got,fout);
	}
//	fprintf(cgiOut, "<span>Before Close</span>\n");
	fclose(fout);
	cgiFormFileClose(file);
	return (0);
}

int uh_urldecode(char *buf, int blen, const char *src, int slen)
{
	int i;
	int len = 0;

#define hex(x) \
	(((x) <= '9') ? ((x) - '0') : \
		(((x) <= 'F') ? ((x) - 'A' + 10) : \
			((x) - 'a' + 10)))

	for( i = 0; (i <= slen) && (i <= blen); i++ )
	{
		if( src[i] == '%' )
		{
			if( ((i+2) <= slen) && isxdigit(src[i+1]) && isxdigit(src[i+2]) )
			{
				buf[len++] = (char)(16 * hex(src[i+1]) + hex(src[i+2]));
				i += 2;
			}
			else
			{
				buf[len++] = '%';
			}
		}
		else
		{
			buf[len++] = src[i];
		}
	}

	return len;
}



void mainf() {
//	  char buf1[80], buf2[80];
//
//	    strcpy(buf1, "When, in the course of...");
//	    memcpy(buf2, buf1, 80);
//	    printf(buf2);
//
//	printf("debug2");
//	char filename[4096];
//	fprintf(stderr,"debug1 %d,%d" ,PATH_MAX ,sizeof(filename));
//
//	const char *ptr="testing";
//	fprintf("t:%s",ptr);
//	memset(filename, 0, sizeof(filename));
//	memcpy(filename, ptr, sizeof(filename));
//
//	fprintf(stderr,"debug1 %d,%d" ,PATH_MAX ,sizeof(filename));
	char dir[PATH_MAX]="/home/sainw/";
//	char *p;
//	p=dir;
//	*p="/home/sainw";

//	scan_dir(dir);
	struct dirent **namelist;
	int n;

//	n = scandir("/", &namelist, 0, alphasort);
//	if (n < 0)
//		perror("scandir");
//	else {
//		while (n--) {
//			printf("%s\n", namelist[n]->d_name);
//			free(namelist[n]);
//		}
//		free(namelist);
//	}
}

